package com.pokemon.web.security;

import com.pokemon.dto.TrainerDTO;
import com.pokemon.services.TrainerService;
import java.text.Normalizer;
import java.text.Normalizer.Form;
import java.util.Arrays;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 *
 * @author Branislav Paulis
 */
public class CustomUserDetailsService implements UserDetailsService {
    
    @Autowired
    private TrainerService trainerService;

    @Override
    public UserDetails loadUserByUsername(String string) throws UsernameNotFoundException {
        List<TrainerDTO> trainers = trainerService.getAllTrainers();
        
        ShaPasswordEncoder encoder = new ShaPasswordEncoder();
        
        CustomUserDetails details = new CustomUserDetails();
        
        if (string.equals("admin")) {
            CustomGrantedAuthority authority = new CustomGrantedAuthority();
            authority.setAuthority("ROLE_ADMIN");
            
            details.setIsAdmin(Boolean.TRUE);
            details.setAuthorities(Arrays.asList(authority));
            details.setUsername("admin");
            details.setPassword(encoder.encodePassword("admin", details.getUsername()));
            
            return details;
        }
        
        for (TrainerDTO trainer : trainers)
        {
            String trainerName = this.normalizeString(trainer.getFirstName() + "_" + trainer.getLastName());
            
            if (string.equals(trainerName)) {
                CustomGrantedAuthority authority = new CustomGrantedAuthority();
                authority.setAuthority("ROLE_USER");
                
                details.setIsAdmin(Boolean.FALSE);
                details.setAuthorities(Arrays.asList(authority));
                
                details.setUsername(trainerName);
                details.setPassword(encoder.encodePassword(trainerName, details.getUsername()));
                details.setTrainer(trainer);    

                return details;
            }
        }
        
        return null;
    }
    
    /**
     * Removes diacritics from string and converts it to lowercase.
     * 
     * @param string string to be normalized
     * @return normalized string
     */
    public static String normalizeString(String string) {
        String result = Normalizer.normalize(string, Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
        return result.toLowerCase();
    }
}